package br.com.arg.aplica.data;

import br.com.arg.aplica.model.Atributo;
import br.com.arg.aplica.model.Classe;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;

import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

//The @Stateful annotation eliminates the need for manual transaction demarcation
@Stateful
//The @Model stereotype is a convenience mechanism to make this a
//request-scoped bean that has an
//EL name
//Read more about the @Model stereotype in this FAQ:
//http://sfwk.org/Documentation/WhatIsThePurposeOfTheModelAnnotation
@Named 
@SessionScoped 
public class ClasseListProducer {
	@Inject
	private EntityManager em;

	private List<Classe> classes;

	// Generated by Map
	private Map<String, Long> mapClasses;
	@Produces	@Named	
	public Map<String, Long> getMapClasse() {
		mapClasses = new LinkedHashMap<String, Long>();
		for (Classe apl : classes) {
			mapClasses.put(apl.getNome(), apl.getId()); // label, value
		}
		return mapClasses;
	}

	// Generated by Map
	private Map<String, Long> mapAtributos;
	@Produces	@Named	
	public Map<String, Long> getMapAtributo() {
		mapAtributos = new LinkedHashMap<String, Long>();
		for (Classe cls : classes) {
			for (Atributo atr : cls.getAtributos()) {
				mapAtributos.put(atr.getNome(), atr.getId()); // label, value
			}
		}
		return mapAtributos;
	}

	@Produces 	@Named
	public List<Classe> getClasses() {
		return classes;
	}

	public void onAplicaListChanged(
			@Observes(notifyObserver = Reception.IF_EXISTS) final Classe classe) {
		retrieveAllClassesOrderedByName();
	}

	@PostConstruct
	public void retrieveAllClassesOrderedByName() {
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<Classe> criteria = cb.createQuery(Classe.class);
		Root<Classe> aplica = criteria.from(Classe.class);
		criteria.select(aplica).orderBy(cb.asc(aplica.get("nome")));
		classes = em.createQuery(criteria).getResultList();
	}
}
